<template>
  <view>
    <!-- 发表评论 -->
    <view class="flex items-center p-20rpx">
      <img :src="props.avatar" class="w-50rpx h-50rpx border-rd-100rpx" />
      <wd-input
        placeholder="请输入内容"
        class="flex-1 border-rd-100rpx ml-20rpx"
        @tap="showRevertPop(0, props.userInfo, null, null)"
      ></wd-input>
    </view>

    <!-- 评论列表 -->
    <view class="h_comment" v-for="(item, index) in commentList" :key="item.id">
      <view class="h-level-1">
        <!-- 用户信息 -->
        <view class="h_info" @tap="showRevertPop(index, item, null, null)">
          <view class="w-full flex items-center justify-between">
            <!-- 用户和头像 -->
            <view class="flex items-center">
              <image size="64rpx" :src="item.url" class="w-64rpx h-64rpx border-rd-[100%]"></image>
              <text class="name fw-700 ml-12rpx" :style="{ color: themeColor }">
                {{ item.name }}
              </text>
            </view>
          </view>
        </view>
        <!-- 一级评论 => 文本 -->
        <view class="h_content" @tap="showRevertPop(index, item, null, null)">
          <text>{{ item.contentText || item.content }}</text>
          <view
            class="images h-400rpx"
            v-for="(e, i) in item.picture"
            :class="[
              imgList.length > 3
                ? 'grid-cols-[1fr_1fr_1fr]'
                : imgList.length === 2
                  ? 'grid-cols-[1fr_1fr]'
                  : 'grid-cols-1fr',
            ]"
            :key="i"
          >
            <!-- <image @click.stop="previewImg()" class="w-full" :src="e" mode="aspectFill"></image> -->
            <wd-img :src="item" :enable-preview="true" class="w-full h-full" />
          </view>
        </view>

        <!-- 一级评论 => 日期、回复 -->
        <view class="h_date">
          <view class="flex items-center text-[#999] text-26rpx">
            <text>{{ item.date }}</text>
            <text class="mx-12rpx">{{ item.ip }}</text>
          </view>
          <view class="like" :style="{ color: item.isLike ? themeColor : '#9a9a9a' }">
            <view class="num" :style="{ color: item.isLike ? themeColor : '#9a9a9a' }">
              {{ item.likeNum }}
            </view>
            <wd-icon
              v-if="!item.isLike"
              name="thumb-up"
              size="36rpx"
              color="#9a9a9a"
              @click.stop="getLike(index)"
            ></wd-icon>
            <wd-icon
              v-if="item.isLike"
              name="thumb-up"
              color="#3670F7"
              size="36rpx"
              @click.stop="getLike(index)"
            ></wd-icon>
          </view>
          <!-- <view
            v-if="item.isMyComment"
            class="h_remove text-26rpx"
            :style="{ color: themeColor }"
            @tap="removeRevertModal(index, item, null, null)"
          >
            删除
          </view> -->
        </view>

        <!-- 二级评论 -->
        <view class="h_revert_list">
          <!-- 二级评论 => 列表 -->
          <view class="item_s" v-for="(item_s, j) in item.replyList" :key="item_s.index">
            <view class="user-info">
              <view class="flex items-center">
                <image
                  size="40rpx"
                  :src="item_s.url"
                  class="w-40rpx h-40rpx border-rd-[100%]"
                ></image>
                <text class="left-name ml-12rpx">
                  {{ item_s.name }}
                </text>
              </view>
              <view class="like" :style="{ color: item_s.isLike ? themeColor : '#9a9a9a' }">
                <view class="num" :style="{ color: item_s.isLike ? themeColor : '#9a9a9a' }">
                  {{ item_s.likeNum }}
                </view>
                <wd-icon
                  v-if="!item_s.isLike"
                  name="thumb-up"
                  size="30rpx"
                  color="#9a9a9a"
                  @click="getLike(index, j)"
                ></wd-icon>
                <wd-icon
                  v-if="item_s.isLike"
                  name="thumb-up"
                  color="#3670F7"
                  size="30rpx"
                  @click="getLike(index, j)"
                ></wd-icon>
              </view>
            </view>
            <view
              class="right-name text-26rpx mt-12rpx ml-50rpx mb-12rpx"
              @tap="showRevertPop(index, item, j, item_s)"
            >
              <text v-if="item_s.to_user_name">回复{{ item_s.to_user_name }}：</text>
              <text class="text text-[#333] text-26rpx">{{ item_s.contentStr }}</text>
            </view>

            <view class="date ml-40rpx">
              <view class="flex items-center text-[#999] text-26rpx">
                <text class="ml-12rpx">{{ item_s.date }}</text>
                <text class="mx-12rpx">{{ item_s.ip }}</text>
              </view>
              <view
                v-if="item_s.user_isMyComment"
                class="h_remove text-26rpx"
                :style="{ color: themeColor }"
                @tap="removeRevertModal(index, item, j, item_s)"
              >
                删除
              </view>
            </view>
          </view>

          <!-- loading -->
          <view v-if="item.isLoading" class="pt-60rpx">
            <wd-loading color="#3670F7" size="30rpx" />
            <text class="text-[#3670F7] ml-8rpx">加载中</text>
          </view>

          <!-- 展开更多二级评论 -->
          <view
            v-if="item.allReply && Number(item.allReply) - item.replyList.length"
            @tap="showAllReply(index, item)"
            class="reply-more"
          >
            <!-- <view class="left-line" /> -->
            展开{{ item.allReply - item.replyList.length }}条回复
          </view>

          <!-- 收起二级评论 -->
          <view
            v-if="item.allReply && Number(item.allReply) === item.replyList.length"
            @tap="closeToAllReply(index)"
            class="reply-more flex-row-center"
          >
            <!-- <view class="left-line" /> -->
            收起回复
            <!-- <u-icon class="more" name="arrow-up" :size="20"></u-icon> -->
          </view>
        </view>
      </view>
    </view>

    <!-- 评论弹框 -->
    <uni-popup ref="revertRef" type="bottom" class="comment-pop" @change="onChangePop">
      <view class="comment-pop-content">
        <wd-input
          :placeholder="placeholder"
          :focus="comtIptFocusStatus"
          v-model="inputVal"
          @change="onChangeInput"
        ></wd-input>
        <view class="send" :style="{ background: '#3670F7' }" @click="sendComment">发送</view>
      </view>
    </uni-popup>
  </view>
</template>

<script setup>
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'

/**
 * 评论组件
 * @props list 评论列表
 * @props modelValue 评论 输入框的value ==> 可使用 v-model 语法糖
 * @props themeColor 主题色
 * @props keyNames 指定keyName 详见文档
 * @event getLike 点赞事件
 * @event sendComment 发送评论事件
 * @event getMore 获取更多评论事件
 * @event remove 删除评论事件
 *
 * @export close 发送评论成功可调用 【close方法】 关闭评论弹框
 *
 * @example <h-comment-box :list="评论列表" v-model="输入框的值" @getLike="点赞回调" @sendComment="发送评论回调" ref="hCommentRef"/>
 */

/**
 * 定义props
 * @param list 评论列表
 * @param modelValue 评论 输入框的value
 * @param themeColor 主题色
 * @param keyNames 指定keyName
 */
const props = defineProps({
  list: {
    type: Array,
  },
  avatar: {
    type: String,
  },
  userInfo: {
    type: Object,
  },
  modelValue: {
    type: String,
    default: '',
  },
  themeColor: {
    type: String,
    default: '#3D3D3D',
  },
  keyNames: {
    type: Object,
    default: () => {
      return {
        // 一级评论相关
        id: 'id', // 评论id
        user_id: 'userId', // 用户id
        user_name: 'name', // 用户名
        user_ip: 'ip', // 用户IP
        user_avatar: 'headshot', // 用户头像
        user_content: 'content', // 用户评论内容
        user_date: 'date', // 用户评论时间
        user_is_like: 'isLike', // 用户是否点赞
        user_like_num: 'likeCount', // 用户点赞数
        isLoading: 'isLoading', // 是否显示加载中
        allReply: 'allReply', // 评论总数
        isMyComment: 'isMyComment', // 是否是自己的评论
        // 二级评论相关
        user_reply_list: 'children', // 回复列表
        user_reply_id: 'userId', // 回复人id
        user_reply_name: 'name', // 回复人名字
        user_reply_avatar: 'headshot', // 回复人头像
        user_reply_content: 'content', // 回复 内容
        user_reply_date: 'date', // 回复 时间
        user_reply_is_like: 'isLike', // 回复人是否点赞
        user_reply_like_num: 'likeCount', // 回复人点赞数
        pid: 'pid',
        user_isMyComment: 'isMyComment', // 是否是自己的评论
        to_user_name: 'to_user_name', // 被回复人名字
        to_user_id: 'to_user_id', // 被回复人id
      }
    },
  },
})

// 定义主题色
const themeColor = ref('#3D3D3D')

// 输入框的placeholder
const placeholder = ref('请输入内容')

// 输入框的value
const inputVal = ref('')

const revertRef = ref(null) // uni_popup 弹框实例
const comtIptFocusStatus = ref(false) // 评论输入框聚焦状态

const isComtIndex = ref(0) // 回复：当前点击的一级评论索引
const isComtRow = ref({}) // 回复：点击的 一级评论信息
const isComtIndex_s = ref(0) // 回复：点击的 二级评论索引
const isComtRow_s = ref({}) // 回复：点击的 二级评论信息

/**
 * 弹框change事件
 */
function onChangePop(e) {
  comtIptFocusStatus.value = e.show
}

/**
 * 发送评论
 */
function sendComment() {
  /**
   * @argument index 一级评论索引
   * @argument row 一级评论信息
   * @argument index_s 二级评论索引
   * @argument row_s 二级评论信息
   * @callback ()=>{} 发送评论接口成功之后 调用sendComment的第二个形参 该形参为方法，更新组件内的评论列表
   */
  emit(
    'sendComment',
    {
      index: isComtIndex.value,
      row: isComtRow.value,
      index_s: isComtIndex_s.value,
      row_s: isComtRow_s.value,
      contentStr: inputVal.value,
    },
    async (data) => {
      if (isComtIndex_s.value !== null) {
        console.log(data, 'if', commentList.value)

        commentList.value[isComtIndex.value].replyList.unshift({ ...data, isMyComment: true })
      } else {
        console.log(data, 'else', commentList.value)

        commentList.value.unshift({ ...data, isMyComment: true })
      }
      close()
    },
  )
}

/**
 * 定义事件
 */
const emit = defineEmits(['getLike', 'sendComment', 'getMore', 'remove', 'update:modelValue'])
defineExpose({
  close,
})

// 评论列表 ==》 根据传入的commentList和传入的keyNames生成新的评论列表
const commentList = ref([])

onLoad(async () => {
  console.log(props.list, 'props.list')
  if (props.list && props.list.length > 0) {
    commentList.value = props.list.map((item) => {
      return {
        id: item[props.keyNames.id],
        name: item[props.keyNames.user_name],
        ip: item[props.keyNames.user_ip],
        url: item[props.keyNames.user_avatar],
        contentText: item[props.keyNames.user_content],
        date: item[props.keyNames.user_date],
        isLike: item[props.keyNames.user_is_like],
        likeNum: item[props.keyNames.user_like_num] || 0,
        isLoading: item[props.keyNames.isLoading],
        allReply: item[props.keyNames.allReply],
        isMyComment: item[props.keyNames.isMyComment],
        replyList:
          (item[props.keyNames.user_reply_list] &&
            item[props.keyNames.user_reply_list].map((item_s) => {
              return {
                id: item_s[props.keyNames.user_reply_id],
                pid: item_s[props.keyNames.pid],
                name: item_s[props.keyNames.user_reply_name],
                ip: item_s[props.keyNames.user_ip],
                url: item_s[props.keyNames.user_reply_avatar],
                contentStr: item_s[props.keyNames.user_reply_content],
                date: item_s[props.keyNames.user_reply_date],
                isLike: item_s[props.keyNames.user_reply_is_like],
                likeNum: item_s[props.keyNames.user_reply_like_num] || 0,
                to_user_name: item_s[props.keyNames.to_user_name],
                to_user_id: item_s[props.keyNames.to_user_id],
                user_isMyComment: item_s[props.keyNames.user_isMyComment],
              }
            })) ||
          [],
      }
    })
    console.log(commentList.value, 'list')
  }
})

/**
 * 回复评论弹框
 * @param index  一级评论索引
 * @param row   一级评论信息
 * @param j  二级评论索引
 * @param row_s 二级评论信息
 */
function showRevertPop(index, row, j, row_s) {
  console.log('展示吧', 111222, row)
  isComtIndex.value = index // 保存当前评论,发送评论时使用
  isComtRow.value = {
    // 保存当前评论,发送评论时使用
    id: row.id,
    name: row.name,
    url: row.url,
    contentText: row.contentText,
    date: row.date,
    isLike: row.isLike,
    likeNum: row.likeNum,
    allReply: row.allReply,
    isMyComment: row.isMyComment,
  }
  if (j !== null) isComtIndex_s.value = j // 保存当前评论,发送评论时使用
  if (j === null) isComtIndex_s.value = null
  if (row_s !== null) {
    isComtRow_s.value = {
      id: row_s.id,
      pid: row_s.pid,
      name: row_s.name,
      url: row_s.url,
      contentStr: row_s.contentStr,
      date: row_s.date,
      isLike: row_s.isLike,
      likeNum: row_s.likeNum,
      user_isMyComment: row_s.user_isMyComment,
    }
  }

  placeholder.value = `回复 @${j !== null ? row_s.name : row.name}`
  openPop()
}

/**
 * 删除评论
 * @param index  一级评论索引
 * @param row   一级评论信息
 * @param j  二级评论索引
 * @param row_s 二级评论信息
 */
function removeRevertModal(index, row, j, row_s) {
  uni.showModal({
    title: '提示',
    content: j === null ? '确定删除该评论吗？' : '确定删除该回复吗？',
    success: (res) => {
      if (res.confirm) {
        emit(
          'remove',
          {
            index,
            row,
            j,
            row_s,
          },
          () => {
            if (j !== null) {
              commentList.value[index].replyList.splice(j, 1)
              commentList.value[index].allReply--
            } else {
              commentList.value.splice(index, 1)
            }
          },
        )
      }
    },
  })
}

/**
 * 打开评论弹框
 */
function openPop() {
  revertRef.value.open()
}

/**
 * 关闭评论弹框
 * @param msg 提示信息 不传则不提示
 */
function close(msg) {
  revertRef.value.close()
  inputVal.value = ''
  if (msg) uni.showToast({ title: msg, icon: 'none' })
}

/**
 * 收起回复
 */
function closeToAllReply(index) {
  commentList.value[index].replyList = []
}

/**
 * 展开更多评论
 * @param index 一级评论索引
 */
function showAllReply(index, row) {
  commentList.value[index].isLoading = true // 显示加载中
  emit('getMore', { index, row }, (data) => {
    let newData = null

    if (Array.isArray(data) && data.length) {
      newData = data.map((item) => {
        return {
          id: item[props.keyNames.user_reply_id],
          pid: item[props.keyNames.pid],
          name: item[props.keyNames.user_reply_name],
          url: item[props.keyNames.user_reply_avatar],
          contentStr: item[props.keyNames.user_reply_content],
          date: item[props.keyNames.user_reply_date],
          isLike: item[props.keyNames.user_reply_is_like],
          likeNum: item[props.keyNames.user_reply_like_num],
          to_user_id: item[props.keyNames.to_user_id],
          to_user_name: item[props.keyNames.to_user_name],
          user_isMyComment: item[props.keyNames.user_isMyComment],
        }
      })

      commentList.value[index].replyList.push(...newData)
    } else {
      newData = {
        id: item[props.keyNames.user_reply_id],
        pid: item[props.keyNames.pid],
        name: item[props.keyNames.user_reply_name],
        url: item[props.keyNames.user_reply_avatar],
        contentStr: item[props.keyNames.user_reply_content],
        date: item[props.keyNames.user_reply_date],
        isLike: item[props.keyNames.user_reply_is_like],
        likeNum: item[props.keyNames.user_reply_like_num],
        to_user_id: item[props.keyNames.to_user_id],
        to_user_name: item[props.keyNames.to_user_name],
        user_isMyComment: item[props.keyNames.user_isMyComment],
      }

      commentList.value[index].replyList.push(newData)
    }

    commentList.value[index].isLoading = false // 关闭加载中
  })
}

/**
 * 点赞
 * @param index 一级评论索引
 * @param j 二级评论索引
 */
function getLike(index, j) {
  /**
   * index 一级评论索引
   * j 二级评论索引
   * ()=>{} 点在接口成功之后 调用getLike的第二个形参 该形参为方法，更新组件内的点赞样式
   */
  emit('getLike', { index, j }, () => {
    if (j !== undefined) {
      commentList.value[index].replyList[j].isLike = !commentList.value[index].replyList[j].isLike
      if (commentList.value[index].replyList[j].isLike == true) {
        commentList.value[index].replyList[j].likeNum++
      } else {
        commentList.value[index].replyList[j].likeNum--
      }
    } else {
      commentList.value[index].isLike = !commentList.value[index].isLike
      if (commentList.value[index].isLike == true) {
        commentList.value[index].likeNum++
      } else {
        commentList.value[index].likeNum--
      }
    }
  })
}

/**
 * 输入框内容改变 => 更新v-model
 */
function onChangeInput(e) {
  emit('update:modelValue', e)
}
</script>

<style lang="scss" scoped>
.h_comment {
  display: flex;
  padding: 20rpx;
  background-color: #fff;
  margin: 20rpx 0;

  .h_left {
    image {
      width: 64rpx;
      height: 64rpx;
      border-radius: 50%;
      background-color: #f2f2f2;
    }
  }

  .h-level-1 {
    flex: 1;
    font-size: 30rpx;

    .h_info {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 10rpx;
    }

    .h_content {
      color: #3d3d3d;
      font-size: 26rpx;
      margin-bottom: 10rpx;
      margin-left: 80rpx;
    }

    .h_date {
      margin-left: 80rpx;
      margin-top: 20rpx;
      display: flex;
      justify-content: space-between;
      font-size: 24rpx;
      color: #9a9a9a;

      .h_revert {
        margin-left: 10rpx;
      }

      .h_remove {
        color: #868686;
        margin-left: 20rpx;
      }

      .like {
        display: flex;
        align-items: center;
        font-size: 26rpx;

        .num {
          margin-right: 4rpx;
        }
      }
    }

    .h_revert_list {
      background-color: #f7f7f7;
      margin-top: 20rpx;
      padding: 0 20rpx;

      .item_s {
        padding-top: 20rpx;

        .user-info {
          display: flex;
          align-items: center;
          justify-content: space-between;

          .username {
            flex: 1;
            font-size: 24rpx;
            color: #999999;
            margin-left: 10rpx;

            .left-name {
              margin-right: 10rpx;
            }

            .right-name {
              margin-left: 10rpx;
            }
          }

          .like {
            display: flex;
            align-items: center;
            color: #9a9a9a;
            font-size: 26rpx;

            .num {
              margin-right: 4rpx;
              color: #9a9a9a;
            }
          }
        }

        .text {
          padding: 8rpx 0;
        }

        .date {
          display: flex;
          align-items: center;
          font-size: 24rpx;
          color: #9a9a9a;

          .revert {
            margin-left: 10rpx;
          }

          .h_remove {
            color: #868686;
            margin-left: 20rpx;
          }
        }
      }

      .reply-more {
        width: 100%;
        padding-top: 20rpx;
        display: flex;
        color: #34d597;
        align-items: center;
        font-size: 24rpx;
        padding-bottom: 20rpx;
        font-weight: 700;

        .left-line {
          width: 50rpx;
          height: 2rpx;
          background-color: #eee;
          margin-right: 10rpx;
        }

        .more {
          margin-left: 6rpx;
        }
      }
    }
  }
}

::v-deep .vue-ref {
  padding-bottom: 0 !important;
}

.comment-pop-content {
  height: 100rpx;
  background-color: #fff;
  display: flex;
  align-items: center;
  justify-content: space-around;

  :deep(.wd-input) {
    width: 70%;
    height: 50rpx;
    border: solid 1rpx #e8e8e8;
    border-radius: 50rpx;
    padding: 0 20rpx;

    .wd-input__body,
    .wd-input__value,
    .wd-input__inner {
      height: 100% !important;
    }
  }

  .wd-input::after {
    display: none;
  }

  .send {
    width: 120rpx;
    height: 40rpx;
    line-height: 40rpx;
    text-align: center;
    border-radius: 60rpx;
    font-size: 26rpx;
    font-weight: 500;
    color: #ffffff;
    margin-left: 18rpx;
  }
}

.p-t-20 {
  padding-top: 20rpx;
}

.flex-row-center {
  justify-content: center;
}

:deep(.wd-input) {
  background: #efefef;
  padding: 0 20rpx;
}

:deep(.wd-input::after) {
  display: none;
}
</style>
